package communication.client.vertx.verticle;

import communication.client.vertx.config.MyLocalServerAutoConfig;
import communication.client.vertx.config.MyRemoteServerAutoConfig;
import communication.common.business.base.*;
import communication.common.business.util.MsgDataUtil;
import communication.common.command.VertxCommand;
import communication.common.shell.FcrServerShell;
import communication.common.vertx.net.NetManager;
import io.vertx.core.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author mac
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class BusinessClientVerticle extends AbstractVerticle{

    private final MyRemoteServerAutoConfig remoteServerAutoConfig;

    private final MyLocalServerAutoConfig localServerAutoConfig;

    private final EventBusManager eventBusManager;

    private final FcrServerShell fcrServerShell;

    private final VertxCommand vertxCommand;

    private final NetManager netManager;

    private final FcrProtocolConfig protocolConfig;

    @PostConstruct
    private void init(){
        // 创建server,注册zxl，登录

        //  zxl2账户创建server,然后登录
        CompositeFuture.all(
//                createServerByDefaultHandler(),
                // 装在自己的command
                vertxCommand.initCommand(),
                // 获取集群的eventBus 并发送消息到server
//                getCluterEventBus(),
                // 创建server，用于发送socket消息
                fcrServerShell.startShellService()
                // 开始检查心跳
//                startCheckHeartBeat()

                // 登录
//                login(MsgDataUtil.createLoginMsgData())
        );
    }


    public Future getCluterEventBus(){
           return eventBusManager.getClusterEventBusFuture(remoteServerAutoConfig.getHost(), remoteServerAutoConfig.getPort())
                   .future()
           .onSuccess(res->{
               if(res){
                   try {
                       eventBusManager.sendMsg("fcr.server","hello,im client",null);
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
               }
           });
    }


    private Future login(MsgData requestData) throws Exception{
        return Future.future(a->{
            Handler<AsyncResult<Void>>[] sendHandler= new Handler[2];
            sendHandler[0]=result -> log.info("client login success.");
            sendHandler[1]=result -> log.error("client login fail.");

            // todo: 优化
            FcrSocketAddress remoteSocketAddress = new FcrSocketAddress(remoteServerAutoConfig.getHost(), remoteServerAutoConfig.getPort());

            try{
                switch (protocolConfig.getType()){
                    case TCP:
                        netManager.sendMsgDataByTcpClient(requestData,remoteSocketAddress);
                        break;
                    case UDP:
                        netManager.sendMsgDataByUdpServer(requestData,remoteSocketAddress,sendHandler);
                        break;
                    default:
                        // nothing
                }
            }catch (Exception e){
                e.printStackTrace();
                a.fail(e.getMessage());
            }
        });
    }


    private Future sendTransferHoleRequest(){
        return Future.future(a->{
            Handler<AsyncResult<Void>>[] sendHandler= new Handler[2];
            sendHandler[0]=result -> log.info("transfer hole success.");
            sendHandler[1]=result -> log.error("transfer hole fail.");


            MsgData transferHoleRequest = MsgDataUtil.createTransferHoleRequest(localServerAutoConfig.getHost(), localServerAutoConfig.getPort());

            // todo: 优化
            FcrSocketAddress remoteSocketAddress = new FcrSocketAddress(remoteServerAutoConfig.getHost(), remoteServerAutoConfig.getPort());


            try{
                switch (protocolConfig.getType()){
                    case TCP:
                        netManager.sendMsgDataByTcpClient(transferHoleRequest,remoteSocketAddress);
                        break;
                    case UDP:
                        netManager.sendMsgDataByUdpServer(transferHoleRequest,remoteSocketAddress,sendHandler);
                        break;
                    default:
                        // nothing
                }
            }catch (Exception e){
                e.printStackTrace();
                a.fail(e.getMessage());
            }
        });
    }

}
